<template>
  <canvas ref="threePractice" class="three-practice"></canvas>
</template>

<script>
import * as THREE from 'three';
// 导入GUI
import { GUI } from "three/examples/jsm/libs/lil-gui.module.min"

import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'

export default {
  name: 'threejsPractice',
  mounted () {
    this.initThree()
  },
  methods: {
    initThree() {
      // 创建场景
      const scene = new THREE.Scene()

      // 创建相机
      const camera = new THREE.PerspectiveCamera(
        45, // 视角
        window.innerWidth / window.innerHeight, // 宽高比
        0.1, // 近平面
        1000 // 远平面
      )

      // 渲染器
      const renderer = new THREE.WebGLRenderer()
      renderer.setSize(window.innerWidth, window.innerHeight)
      document.body.appendChild(renderer.domElement)

      // 创建几何体
      const geometry = new THREE.BoxGeometry(1, 1, 1)
      // 创建材质
      const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 })
      const parentMaterial = new THREE.MeshBasicMaterial({color: 0xff0000})
      // 设置父元素材质为线框模式
      parentMaterial.wireframe = true
      // 创建网格
      let parentCub = new THREE.Mesh(geometry, parentMaterial);
      const cube = new THREE.Mesh(geometry, material)
      parentCub.add(cube)
      parentCub.position.set(-3, 0, 0)
      parentCub.rotation.x = Math.PI / 4
      // parentCub.scale.set(2, 2, 2)

      // 设置位移
      // cube.position.x = 2
      cube.position.set(3, 0, 0)
      // 设置立方体放大
      // cube.scale.set(2, 2, 2)
      // 绕着x轴旋转
      cube.rotation.x = Math.PI / 4;

      // 将网格添加到场景中
      scene.add(parentCub)

      // 设置相机位置
      camera.position.x = 2
      camera.position.z = 5
      camera.position.y = 2
      camera.lookAt(0, 0, 0)

      // 添加世界坐标辅助器（线段长度）
      const axesHelper = new THREE.AxesHelper(5);
      scene.add(axesHelper)

      // 添加轨道控制器
      const controls = new OrbitControls(camera, renderer.domElement)
      // 设置带阻尼的惯性
      controls.enableDamping = true
      // 设置阻尼系数
      controls.dampingFactor = 0.05
      // 设置旋转速度
      // controls.autoRotate = true

      // 渲染场景
      renderer.render(scene, camera)

      const animate = () => {
        controls.update()

        requestAnimationFrame(animate)
        // 旋转
        /*cube.rotation.x += 0.01
        cube.rotation.y += 0.01*/

        // 渲染
        renderer.render(scene, camera)
      }
      animate()

      // 监听窗口变化
      window.addEventListener('resize', () => {
        // 重置渲染器宽高比
        renderer.setSize(window.innerWidth, window.innerHeight)
        // 重置相机宽高比
        camera.aspect = window.innerWidth / window.innerHeight
        // 更新相机投影矩阵
        camera.updateProjectionMatrix()
      })

      let eventObj = {
        Fullscreen: function () {
          document.body.requestFullscreen()
        },
        ExitFullscreen: function () {
          document.exitFullscreen()
        }
      }

      const gui = new GUI();
      gui.add(eventObj, "Fullscreen").name("全屏")
      gui.add(eventObj, "ExitFullscreen").name("退出全屏")

      // 控制立方体位置
      let folder = gui.addFolder("立方体位置")
      folder.add(cube.position, "x", -5, 5).name("立方体x轴位置").step(1).onChange((val) => {
        console.log(val)
      }).onFinishChange((val) => {
        console.log(val)
      })
      folder.add(cube.position, "y", -5, 5).name("立方体y轴位置").step(1)
      folder.add(cube.position, "z", -5, 5).name("立方体z轴位置").step(1)

      gui.add(parentMaterial, "wireframe").name("父元素线框模式")

      let colorParams = {
        cubeColor: "#ff0000"
      }
      gui.addColor(colorParams, "cubeColor").name("立方体颜色").onChange((val) => {
        cube.material.color.set(val)
      })
    },
  }
}
</script>

<style scoped>
.three-practice {
  position: fixed;
  top: 0;
  left: 0;
}
</style>
